package com.xique.common.datascope.aspect;

import com.xique.common.core.constant.Constants;
import com.xique.common.core.constant.HttpStatus;
import com.xique.common.core.domain.R;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.datascope.annotation.NeedSetDictParam;
import com.xique.system.api.RemoteSystemDictService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Objects;

/**
 * 公共的调用方法
 *
 * 用于-切面加注解联表查询
 * @author xl.liu
 *
 */
@Component
public class SetDictLableUtil implements ApplicationContextAware {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private RemoteSystemDictService dictService;

    @Autowired
    private CacheManager cacheManager;

    private Cache dictCache;

    @PostConstruct
    public void init()
    {
    	dictCache =  cacheManager.getCache(Constants.SYS_DICT_KEY);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (this.applicationContext == null ) {
            this.applicationContext = applicationContext;
        }
    }

    //单个实体赋值
    public void setValue(Object obj) throws Exception{
        if (Objects.isNull(obj)){
            return;
        }
    	 Class<?> clazz = obj.getClass();
         Field[] fields = clazz.getDeclaredFields();
         for (Field field : fields) {
         	NeedSetDictParam sv = field.getAnnotation(NeedSetDictParam.class);
             if (sv == null) {
                 continue;
             }
            field.setAccessible(true);
            //字典类型
            String dictType = sv.dictType();
            //字典值
             Field valueField = clazz.getDeclaredField(sv.dictValue());
             valueField.setAccessible(true);
             String keyPrefix = Constants.SYS_DICT_KEY + "-" + dictType;
             Object paramValue = valueField.get(obj);
             if (paramValue == null) {
                 continue;
             }
             Object value = null;
             // 先从缓存中拿
             String key = keyPrefix + paramValue;
             if (null != dictCache.get(key)) {
                 value = dictCache.get(key);
                 if (value instanceof SimpleValueWrapper) {
                     value = ((SimpleValueWrapper) value).get();
                 }
                 if (value instanceof R) {
                     value = ((R) value).getData();
                 }
                 if (StringUtils.isNull(value)) {
                     dictCache.evict(key);
                 }
             } else {
                 R<String> result = dictService.getDictLabel(sv.dictType(), paramValue.toString());
                 if (R.SUCCESS == result.getCode()) {
                     value = result.getData();
                 }
                 dictCache.put(key,value);
             }
             field.set(obj, value);
         }
    }

    //集合赋值
    public void setValue(Collection col) throws Exception {
        Class<?> clazz = col.iterator().next().getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            NeedSetDictParam sv = field.getAnnotation(NeedSetDictParam.class);
            if (sv == null) {
                continue;
            }
            field.setAccessible(true);
        	//字典类型
        	String dictType = sv.dictType();
        	//字典值
            Field valueField = clazz.getDeclaredField(sv.dictValue());
            valueField.setAccessible(true);
            //Map<String, Object> cache = new HashMap<>();
            String keyPrefix = Constants.SYS_DICT_KEY + dictType;
            for (Object obj : col) {
                Object paramValue = valueField.get(obj);
                if (paramValue == null) {
                    continue;
                }
                 Object value = null;
             // 先从缓存中拿
                String key = keyPrefix + "-" + paramValue;
                if (null != dictCache.get(key)) {
                    value = dictCache.get(key);
                    if (value instanceof SimpleValueWrapper) {
                        value = ((SimpleValueWrapper) value).get();
                    }
                } else {
                    R<String> result = dictService.getDictLabel(dictType, paramValue.toString());
                    if (result.getCode() == HttpStatus.SUCCESS) {
                        value = result.getData();
                    }
                    dictCache.put(key, value);
                }
                field.set(obj, value);
            }
        }
    }
}

